#include<iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
using namespace std;

int main()
{
    //1.创建socket
    int sfd = socket(AF_INET, SOCK_STREAM, 0);

    //2.绑定端口和ip地址，bind
    //定义sockaddr_in
    struct sockaddr_in server_sockaddr;
    server_sockaddr.sin_family = AF_INET;//TCP/IP协议族
    server_sockaddr.sin_port = htons(8023);//端口号
    server_sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");//ip地址，127.0.0.1是环回地址，相当于本机ip

    if(bind(sfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr)) == -1)//指明链接套接字，本机ip地址和端口，地址长度
    {
        //绑定失败
        perror("bind");//输出错误原因
        exit(1);//结束程序
    }

    //3.监听socket，lisent
    if(listen(sfd, 20) == -1)//指明链接套接字，最大可连接服务器的客户端量
    {
        perror("listen");//输出错误原因
        exit(1);//结束程序
    }

    //4.获取客户端链接，accept
    //客户端套接字
    struct sockaddr_in client_addr;
    socklen_t length = sizeof(client_addr);
    int cfd = accept(sfd, (struct sockaddr*)&client_addr, &length);//连接套接字,客户端ip地址，客户端ip长度
    if(cfd == -1)
    {
        perror("connect");//输出错误原因
        exit(1);//结束程序
    }
    cout<<"客户端成功连接\n 客户端 ID: " << cfd ;

    //5.接收/发送消息，recv，send
    char buffer[1024];
    while(1) {
        memset(buffer, 0, sizeof(buffer));//清零
        int len = recv(cfd, buffer, sizeof(buffer), 0);
        //客户端发送exit或者异常结束时，退出
        if(strcmp(buffer, "exit") == 0 || len <= 0)
            break;
        cout << "Client: " << buffer << endl;
    }

    //6.关闭链接close
    close(cfd);
    close(sfd);
    return 0;
}
